package com.zsc.springcloud.controller;

import com.google.common.util.concurrent.RateLimiter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.concurrent.TimeUnit;

@Slf4j
@RestController
public class RateLimiterController {

    RateLimiter rateLimiter =  RateLimiter.create(2.0);

    /**
     * 非阻塞限流
     * 1.rateLimiter具有令牌缓存功能，在初次访问时，可以拿到足够的令牌
     * 非阻塞限流： 如果获取不到令牌，返回失败
     */
    @GetMapping("/tryAcquire")
    public String tryAcquire(Integer count){
        if (rateLimiter.tryAcquire(count)){
            log.info("success,rate is {}",rateLimiter.getRate());
            return "success";
        }else {
            log.info("fail, rate is {}",rateLimiter.getRate());
            return "fail";
        }
    }

    /**
     * 限定时间的非阻塞限流
     * 非阻塞限流-限定时间的话： 请求会等待timeout，如果还获取不到令牌，返回失败
     * 在要求在规定时间内获取到的令牌数远无法满足条件时，直接返回失败
     */
    @GetMapping("/tryAcquireWithTimeout")
    public String tryAcquireWithTimeout(Integer count,Integer timeout){
        if (rateLimiter.tryAcquire(count,timeout, TimeUnit.SECONDS)){
            log.info("success,rate is {}",rateLimiter.getRate());
            return "success";
        }else {
            log.info("fail, rate is {}",rateLimiter.getRate());
            return "fail";
        }
    }

    /**
     * 同步阻塞限流
     *
     */
    @GetMapping("/acquire")
    public String acquire(Integer count,Integer timeout){
        rateLimiter.acquire(count);
        log.info("success,rate is {}",rateLimiter.getRate());
        return "success";
    }

    /**
     * nginx专用
     * 1,修改host文件配置域名对应127.0.0.1
     * 2.修改nginx->将步骤1的域名，添加到路由规则
     * 3.添加配置：见resources
     *
     */
    @GetMapping("/nginx")
    public String nginx(Integer count,Integer timeout){
        return "success";
    }


    @GetMapping("/nginxConn")
    public String nginxConn(@RequestParam(defaultValue = "0") int secs){
        try {
            Thread.sleep(1000*secs);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "success";
    }



}
